Skip to content

feat(FoRadialProgress): First implementation#135

Merged
michaelcozzolino merged 4 commits into2.xfrom
feat/radial-progress
Feb 25, 2026
Merged

feat(FoRadialProgress): First implementation#135
michaelcozzolino merged 4 commits into2.xfrom
feat/radial-progress

Conversation

@michaelcozzolino
Copy link
Owner

@michaelcozzolino michaelcozzolino commented Feb 25, 2026

Summary by CodeRabbit

  • New Features

    • Introduced RadialProgress component with customizable colors, background presets (including soft), sizes, and thickness.
    • RadialProgress is now available from the UI components index.
  • Documentation

    • Added comprehensive RadialProgress docs and multiple example previews (variants, colors, backgrounds, sizes).
    • Added RadialProgress entry to the docs sidebar for easy discovery.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Walkthrough

This pull request adds a new FoRadialProgress component with accompanying TypeScript types (RadialProgressProps, RadialProgressBackgroundProps), registers it in the public UI exports and app config, and integrates it with the color utility by centralizing color-to-class mappings and updating the useColor signature to accept the app config. It also adds documentation pages and demo components for RadialProgress and renames the Avatar docs section heading from "Variants" to "Presets".

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the primary change: introducing the first implementation of the FoRadialProgress component with all supporting types, configuration, and documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/radial-progress

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
packages/core/src/UI/Components/RadialProgress/Types/RadialProgress.ts (2)

9-9: Document the valid range for value.

value: number accepts any number, but the underlying --value CSS variable is meaningful only in the 0–100 range. A JSDoc note prevents misuse.

✏️ Proposed addition
-    /** The progress' value */
-    value: number;
+    /**
+     * The progress' value (0–100).
+     */
+    value: number;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/UI/Components/RadialProgress/Types/RadialProgress.ts` at
line 9, Add a JSDoc comment to the RadialProgress type's value property (the
`value: number` declaration) documenting that the valid range is 0–100 and that
this number maps to the underlying `--value` CSS variable; place the note
directly above the `value` field in the RadialProgress type so developers know
to supply/clamp values to that range.

7-12: Consider making color and background mutually exclusive at the type level.

The comment on line 11 documents that color is silently ignored when background is set, but the type still permits both to be provided simultaneously. A discriminated union would surface this conflict statically instead of relying on a comment.

♻️ Proposed type-safe alternative
-export interface RadialProgressProps extends Colorable {
-    /** The progress' value */
-    value: number;
-
-    /** The progress' background style, if this is set, the color prop will be ignored */
-    background?: RadialProgressBackgroundProps;
-}
+type RadialProgressBaseProps = {
+    /** The progress' value */
+    value: number;
+};
+
+export type RadialProgressProps =
+    | (RadialProgressBaseProps & Colorable & { background?: never })
+    | (RadialProgressBaseProps & { color?: never; background: RadialProgressBackgroundProps });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/UI/Components/RadialProgress/Types/RadialProgress.ts`
around lines 7 - 12, RadialProgressProps currently allows both color (from
Colorable) and background (RadialProgressBackgroundProps) simultaneously even
though color is ignored when background is present; change RadialProgressProps
to a discriminated union so the two are mutually exclusive — one branch extends
Colorable and allows color but sets background?: never, and the other branch
requires background: RadialProgressBackgroundProps and excludes color (or sets
color?: never); update any uses or helpers accordingly (or create an XOR<T,U>
utility and use XOR<Colorable, { background: RadialProgressBackgroundProps }>)
so TypeScript surfaces the conflict at compile time.
packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue (1)

38-64: Consider narrowing colorClasses to only supported presets.

The Record<Preset, ...> type requires entries for all 7 presets, but only solid and soft produce meaningful classes. The other 5 map to empty strings, which silently degrades to an unstyled state. Since RadialProgressBackgroundPreset is reportedly 'solid' | 'soft', you could type colorClasses as Record<RadialProgressBackgroundPreset, Record<Color, string>> and avoid the need for the emptyColorClasses placeholder entirely.

#!/bin/bash
# Verify RadialProgressBackgroundPreset type
rg -n "RadialProgressBackgroundPreset" --type ts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`
around lines 38 - 64, The colorClasses map is typed as Record<Preset,
Record<Color, string>> but only 'solid' and 'soft' are meaningful; change its
type to Record<RadialProgressBackgroundPreset, Record<Color, string>> and remove
the emptyColorClasses placeholders so only solid and soft entries are defined.
Update the declaration of colorClasses (symbol: colorClasses) and the referenced
types (Preset, Color) to use RadialProgressBackgroundPreset instead, and delete
or stop using emptyColorClasses in this file (symbol: emptyColorClasses) so the
type matches the actual supported presets.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`:
- Around line 1-8: The progressbar div in FoRadialProgress.vue is missing
required ARIA attributes; update the element with role="progressbar" to include
aria-valuenow bound to the component's value prop and
aria-valuemin/aria-valuemax bound to min and max props (use sensible defaults
like 0 and 100 if min/max props don't exist—add them to the component props as
needed), ensuring the attributes reflect numeric values so screen readers can
convey progress state.

In `@packages/docs/Next/Components/RadialProgress.md`:
- Line 39: Update the section header "## Api" to use the correct capitalization
for the initialism by changing the heading text from "## Api" to "## API" in the
RadialProgress markdown (look for the heading line "## Api").

In
`@packages/docs/Next/Components/RadialProgress/RadialProgressSoftBackground.vue`:
- Around line 1-47: The soft-background showcase is missing the neutral variant;
add another FoRadialProgress instance using :background="{ color: 'neutral',
preset: 'soft' }" with the same :value="70" and slot content "70%" so the
component (FoRadialProgress) demonstrates the neutral color alongside
primary/secondary/accent/etc.; place it alongside the other soft-background
examples to maintain ordering and consistency.

---

Nitpick comments:
In `@packages/core/src/UI/Components/RadialProgress/Types/RadialProgress.ts`:
- Line 9: Add a JSDoc comment to the RadialProgress type's value property (the
`value: number` declaration) documenting that the valid range is 0–100 and that
this number maps to the underlying `--value` CSS variable; place the note
directly above the `value` field in the RadialProgress type so developers know
to supply/clamp values to that range.
- Around line 7-12: RadialProgressProps currently allows both color (from
Colorable) and background (RadialProgressBackgroundProps) simultaneously even
though color is ignored when background is present; change RadialProgressProps
to a discriminated union so the two are mutually exclusive — one branch extends
Colorable and allows color but sets background?: never, and the other branch
requires background: RadialProgressBackgroundProps and excludes color (or sets
color?: never); update any uses or helpers accordingly (or create an XOR<T,U>
utility and use XOR<Colorable, { background: RadialProgressBackgroundProps }>)
so TypeScript surfaces the conflict at compile time.

In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`:
- Around line 38-64: The colorClasses map is typed as Record<Preset,
Record<Color, string>> but only 'solid' and 'soft' are meaningful; change its
type to Record<RadialProgressBackgroundPreset, Record<Color, string>> and remove
the emptyColorClasses placeholders so only solid and soft entries are defined.
Update the declaration of colorClasses (symbol: colorClasses) and the referenced
types (Preset, Color) to use RadialProgressBackgroundPreset instead, and delete
or stop using emptyColorClasses in this file (symbol: emptyColorClasses) so the
type matches the actual supported presets.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec7d498 and 94e9a56.

⛔ Files ignored due to path filters (7)
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-background-color-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-color-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-custom-size-and-thickness-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-default-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-soft-background-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-with-text-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/components-radial-progress-with-value-chromium-linux.png is excluded by !**/*.png
📒 Files selected for processing (21)
  • packages/core/src/Lib/UseColor/Internal/Lib/UseColor.ts
  • packages/core/src/Lib/UseColor/Types/Color.ts
  • packages/core/src/Lib/UseFlyonUIVueAppConfig/Types/FlyonUIVueAppConfig.ts
  • packages/core/src/UI/Components/RadialProgress/Types/RadialProgress.ts
  • packages/core/src/UI/Components/RadialProgress/Types/index.ts
  • packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue
  • packages/core/src/UI/Components/RadialProgress/UI/index.ts
  • packages/core/src/UI/Components/RadialProgress/index.ts
  • packages/core/src/UI/Components/index.ts
  • packages/docs/.vitepress/theme/Components/Layout/Features/Sidebar/Lib/UseSidebarItems.ts
  • packages/docs/.vitepress/theme/index.ts
  • packages/docs/Next/Components/Avatar.md
  • packages/docs/Next/Components/RadialProgress.md
  • packages/docs/Next/Components/RadialProgress/CustomRadialProgressSizeAndThickness.vue
  • packages/docs/Next/Components/RadialProgress/DefaultRadialProgress.vue
  • packages/docs/Next/Components/RadialProgress/RadialProgressBackgroundColor.vue
  • packages/docs/Next/Components/RadialProgress/RadialProgressColor.vue
  • packages/docs/Next/Components/RadialProgress/RadialProgressDocs.vue
  • packages/docs/Next/Components/RadialProgress/RadialProgressSoftBackground.vue
  • packages/docs/Next/Components/RadialProgress/RadialProgressWithText.vue
  • packages/docs/Next/Components/RadialProgress/RadialProgressWithValue.vue

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 25, 2026

Deploying flyonui-vue-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 663a50c
Status: ✅  Deploy successful!
Preview URL: https://c00ed973.flyonui-vue-v3.pages.dev
Branch Preview URL: https://feat-radial-progress.flyonui-vue-v3.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

Deploying flyonui-vue with  Cloudflare Pages  Cloudflare Pages

Latest commit: 663a50c
Status: ✅  Deploy successful!
Preview URL: https://f69b1a4e.flyonui-vue.pages.dev
Branch Preview URL: https://feat-radial-progress.flyonui-vue.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue (1)

5-7: ⚠️ Potential issue | 🟠 Major

aria-valuemin and aria-valuemax are still missing from the progressbar element.

aria-valuenow was added, but the WCAG-required aria-valuemin and aria-valuemax remain absent. Screen readers cannot convey relative progress without all three.

♿ Proposed fix
         role="progressbar"
         :aria-valuenow="value"
+        aria-valuemin="0"
+        aria-valuemax="100"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`
around lines 5 - 7, The progressbar element in FoRadialProgress.vue sets
:aria-valuenow="value" but is missing aria-valuemin and aria-valuemax; add bound
attributes (e.g., :aria-valuemin="min" and :aria-valuemax="max") on the same
element and ensure the component exposes props or computed values named min and
max (with sensible defaults, e.g., 0 and 100) so the screen reader can infer the
range relative to :aria-valuenow="value".
🧹 Nitpick comments (1)
packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue (1)

28-65: Static lookup tables are reconstructed on every computed evaluation.

emptyColorClasses and colorClasses are pure constants with no dependency on reactive state. Defining them inside the computed getter causes fresh object allocation on every recompute. Hoist them to module-level constants.

♻️ Proposed refactor
+const emptyColorClasses: Record<Color, ''> = {
+    neutral: '', primary: '', secondary: '', accent: '',
+    info: '',   success: '', warning: '',   error: '',
+};
+
+const colorClasses: Record<Preset, Record<Color, string>> = {
+    solid: {
+        neutral:   'bg-neutral text-neutral-content border-4 border-transparent',
+        primary:   'bg-primary text-primary-content border-4 border-transparent',
+        secondary: 'bg-secondary text-secondary-content border-4 border-transparent',
+        accent:    'bg-accent text-accent-content border-4 border-transparent',
+        info:      'bg-info text-info-content border-4 border-transparent',
+        success:   'bg-success text-success-content border-4 border-transparent',
+        warning:   'bg-warning text-warning-content border-4 border-transparent',
+        error:     'bg-error text-error-content border-4 border-transparent',
+    },
+    outline:  emptyColorClasses,
+    dash:     emptyColorClasses,
+    soft: {
+        neutral:   'bg-neutral/10 text-neutral border-4 border-transparent',
+        primary:   'bg-primary/10 text-primary border-4 border-transparent',
+        secondary: 'bg-secondary/10 text-secondary border-4 border-transparent',
+        accent:    'bg-accent/10 text-accent border-4 border-transparent',
+        info:      'bg-info/10 text-info border-4 border-transparent',
+        success:   'bg-success/10 text-success border-4 border-transparent',
+        warning:   'bg-warning/10 text-warning border-4 border-transparent',
+        error:     'bg-error/10 text-error border-4 border-transparent',
+    },
+    gradient: emptyColorClasses,
+    text:     emptyColorClasses,
+    dot:      emptyColorClasses,
+};

 const backgroundClass = computed((): string => {
-    const emptyColorClasses: Record<Color, ''> = { ... };
-    const colorClasses: Record<Preset, Record<Color, string>> = { ... };
     // ...
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`
around lines 28 - 65, The two lookup objects emptyColorClasses and colorClasses
are being recreated inside a computed getter; hoist them to module scope as true
constants to avoid reallocation on each computed evaluation. Move the const
declarations for emptyColorClasses: Record<Color, ''> and colorClasses:
Record<Preset, Record<Color, string>> out of the component/computed block to the
top-level of the module (keeping their exact names and type annotations), then
update any references in the computed/getter to use these module-level
constants.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`:
- Line 70: The direct double-index access
colorClasses[defaultPreset][defaultColor] can throw if
colorClasses[defaultPreset] is undefined; change the return to perform a guarded
lookup and provide a safe fallback: first check colorClasses and
colorClasses[defaultPreset] exist (or use optional chaining) before indexing
with defaultColor, and return a sensible default class (e.g., an empty string or
a known fallback key) when either defaultPreset or defaultColor is
missing/invalid; update the logic around the colorClasses, defaultPreset and
defaultColor variables (and any use of useFlyonUIVueAppConfigProperty) to use
this defensive lookup so runtime TypeError is avoided.
- Around line 67-68: Move the two useFlyonUIVueAppConfigProperty calls out of
the computed getter and up to the top level of setup: create defaultPreset =
useFlyonUIVueAppConfigProperty(config, componentName, 'preset', () =>
props.background?.preset) and defaultColor =
useFlyonUIVueAppConfigProperty(config, componentName, 'color', () =>
props.background?.color) inside setup, then reference defaultPreset.value and
defaultColor.value inside your computed getter instead of calling the composable
there; this avoids creating nested computed refs and preserves reactivity by
passing callbacks for props.

---

Duplicate comments:
In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`:
- Around line 5-7: The progressbar element in FoRadialProgress.vue sets
:aria-valuenow="value" but is missing aria-valuemin and aria-valuemax; add bound
attributes (e.g., :aria-valuemin="min" and :aria-valuemax="max") on the same
element and ensure the component exposes props or computed values named min and
max (with sensible defaults, e.g., 0 and 100) so the screen reader can infer the
range relative to :aria-valuenow="value".

---

Nitpick comments:
In `@packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue`:
- Around line 28-65: The two lookup objects emptyColorClasses and colorClasses
are being recreated inside a computed getter; hoist them to module scope as true
constants to avoid reallocation on each computed evaluation. Move the const
declarations for emptyColorClasses: Record<Color, ''> and colorClasses:
Record<Preset, Record<Color, string>> out of the component/computed block to the
top-level of the module (keeping their exact names and type annotations), then
update any references in the computed/getter to use these module-level
constants.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94e9a56 and 663a50c.

📒 Files selected for processing (1)
  • packages/core/src/UI/Components/RadialProgress/UI/FoRadialProgress.vue

@michaelcozzolino michaelcozzolino merged commit bade25d into 2.x Feb 25, 2026
7 checks passed
@michaelcozzolino michaelcozzolino deleted the feat/radial-progress branch February 25, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant